#!/bin/bash
#set -e
# ============ 平台检测 =============
detect_platform() {
    case "$(uname -s)" in
        Darwin)
            OS="macOS"
            SHA_TOOL="shasum"
            OPEN_CMD="open"
            FILE_VMOPTIONS=".vmoptions"
            ;;
        Linux)
            OS="Linux"
            SHA_TOOL="sha1sum"
            OPEN_CMD="xdg-open"
            FILE_VMOPTIONS="64.vmoptions"
            ;;
        *)
            OS="Unknown"
            SHA_TOOL="sha1sum"
            OPEN_CMD="xdg-open"
            FILE_VMOPTIONS=".vmoptions"
            ;;
    esac
}
detect_platform
# ============ 配置 =============
DEBUG=false
ENABLE_COLOR=true

# Alist下载配置
BASE_URL="https://gitee.com/MagicCoderShow/pan/raw/master/Activate/"
# License下载地址
LICENSE_URL="https://gitee.com/MagicCoderShow/pan/raw/master/Activate/jar/code.key"
# Jetbra下载地址
JETBRA_URL="https://gitee.com/MagicCoderShow/pan/raw/master/Activate/jar/jetbra-script.zip"

# 用户路径处理
if [ "$(id -u)" -eq 0 ] && [ -n "$SUDO_USER" ]; then
    ORIGINAL_USER="$SUDO_USER"
    USER_HOME="/home/${SUDO_USER}"
else
    ORIGINAL_USER="$(whoami)"
    USER_HOME="${HOME}"
fi

# macOS 用户路径修正
if [[ "$OS" == "macOS" ]]; then
    USER_HOME="/Users/${ORIGINAL_USER}"
fi

# 工作路径配置
dir_work="${USER_HOME}/.jb_run"
dir_config="${dir_work}/config"
dir_plugins="${dir_work}/plugins"
file_netfilter_jar="${dir_work}/ja-netfilter.jar"

# JetBrains 目录配置
if [[ "$OS" == "macOS" ]]; then
    dir_cache_jb="${USER_HOME}/Library/Caches/JetBrains"
    dir_config_jb="${USER_HOME}/Library/Application Support/JetBrains"
else
    dir_cache_jb="${USER_HOME}/.cache/JetBrains"
    dir_config_jb="${USER_HOME}/.config/JetBrains"
fi

# 日志颜色设置
if $ENABLE_COLOR; then
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[0;33m'
    GRAY='\033[38;5;240m'
    NC='\033[0m'  # 重置颜色
else
    RED=''
    GREEN=''
    YELLOW=''
    GRAY=''
    NC=''
fi

# 产品列表配置
PRODUCTS='[
    {"name":"idea","productCode":"II,PCWMP,PSI"},
    {"name":"clion","productCode":"CL,PSI,PCWMP"},
    {"name":"phpstorm","productCode":"PS,PCWMP,PSI"},
    {"name":"goland","productCode":"GO,PSI,PCWMP"},
    {"name":"pycharm","productCode":"PC,PSI,PCWMP"},
    {"name":"webstorm","productCode":"WS,PCWMP,PSI"},
    {"name":"rider","productCode":"RD,PDB,PSI,PCWMP"},
    {"name":"datagrip","productCode":"DB,PSI,PDB"},
    {"name":"rubymine","productCode":"RM,PCWMP,PSI"},
    {"name":"appcode","productCode":"AC,PCWMP,PSI"},
    {"name":"dataspell","productCode":"DS,PSI,PDB,PCWMP"},
    {"name":"dotmemory","productCode":"DM"},
    {"name":"rustrover","productCode":"RR,PSI,PCWP"}
]'

# ============ 工作目录创建 =============
do_create_work_dir() {
    if [[ "${dir_work}" == "/" || -z "${dir_work}" ]]; then
        error "检测到非法路径: ${dir_work}，请检查配置。"
        exit 1
    fi
    if [ -d "${dir_work}" ]; then
        rm -rf "${dir_work}" || {
            error "文件被占用，请先关闭所有Jetbrains IDE后再试！"
            exit 1
        }
    fi
    mkdir -p "${dir_work}" || {
        error "创建工作目录失败: ${dir_work}"
        exit 1
    }
    debug "创建工作目录: ${dir_work}"
}

# ============ 工具函数 =============
log() {
    local level="$1"
    local message="$2"
    local color=""
    case "$level" in
        "INFO") color="$NC" ;;
        "DEBUG") [[ "$DEBUG" == true ]] || return; color="$GRAY" ;;
        "WARNING") color="$YELLOW" ;;
        "ERROR") color="$RED" ;;
        "SUCCESS") color="$GREEN" ;;
        *) color="$NC" ;;
    esac
    echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')][$level] ${message}${NC}"
}
debug()   { log "DEBUG" "$1"; }
info()    { log "INFO" "$1"; }
warning() { log "WARNING" "$1"; }
error()   { log "ERROR" "$1"; }
success() { log "SUCCESS" "$1"; }

show_ascii_weclome() {
    echo "                 欢迎使用本脚本                    "
}

# ============ 清理并更新 .vmoptions 文件 =============
clean_vmoptions() {
    local file="$1"
    if [ ! -f "$file" ]; then
        debug "清理vm: 文件不存在，跳过清理: $file"
        return 0
    fi

    local temp_lines=()
    local keywords=(
        "-javaagent"
        "--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED"
        "--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED"
    )

    while IFS= read -r line; do
        local matched=false
        for keyword in "${keywords[@]}"; do
            [[ "$line" == *"$keyword"* ]] && matched=true && break
        done
        [[ "$matched" == false ]] && temp_lines+=("$line")
    done < "$file"

    printf "%s\n" "${temp_lines[@]}" > "$file"
    debug "清理vm: $file"
}
append_vmoptions() {
    local file="$1"
    if [ ! -f "$file" ]; then
        touch "$file" || {
            error "生成vm: 创建失败: $file"
            return
        }
    fi

    cat >> "$file" <<EOF
--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED
--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
-javaagent:${file_netfilter_jar}

EOF

    debug "生成vm: $file"
}
clean_vmoptions() {
    local file="$1"
    if [ ! -f "$file" ]; then
        touch "$file" || {
            error "生成vm: 创建失败: $file"
            return
        }
    fi

    cat >> "$file" <<EOF
--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED
--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
-javaagent:${file_netfilter_jar}

EOF

    debug "生成vm: $file"
}


# ============ 核心功能函数 =============

# 依赖检查与安装
check_and_install_deps() {
    local deps=("curl" "jq")
    local missing=()
    for dep in "${deps[@]}"; do
        if ! command -v "$dep" &>/dev/null; then missing+=("$dep"); fi
    done
    [ ${#missing[@]} -eq 0 ] && { info "所有依赖已安装。"; return; }

    warning "缺少以下依赖：${missing[*]}，正在尝试自动安装..."
    case "$(uname -s)" in
        Darwin)
            if ! command -v brew &>/dev/null; then
                warning "检测到 macOS 但未安装 Homebrew"
                read -p "是否要自动安装 Homebrew?(y/n) " install_brew
                if [[ "$install_brew" =~ [yY] ]]; then
                    info "正在安装 Homebrew..."
                    /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
                    if [ -x "/opt/homebrew/bin/brew" ]; then
                        echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc
                        source ~/.zshrc
                    elif [ -x "/usr/local/bin/brew" ]; then
                        echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zshrc
                        source ~/.zshrc
                    fi
                    if ! command -v brew &>/dev/null; then
                        error "Homebrew 安装后仍不可用，请手动重启终端后重试"
                        exit 1
                    fi
                else
                    error "必须安装 Homebrew 才能继续!"
                    exit 1
                fi
            fi
            brew install "${missing[@]}"
            ;;
        Linux)
            if command -v apt-get &>/dev/null; then
                sudo apt update && sudo apt install -y "${missing[@]}"
            elif command -v dnf &>/dev/null; then
                sudo dnf install -y "${missing[@]}"
            elif command -v yum &>/dev/null; then
                sudo yum install -y "${missing[@]}"
            elif command -v pacman &>/dev/null; then
                sudo pacman -Sy --noconfirm "${missing[@]}"
            else
                error "无法识别的 Linux 发行版，请手动安装依赖：${missing[*]}"
                exit 1
            fi
            ;;
        *)
            error "不支持的操作系统"
            exit 1
            ;;
    esac
    for dep in "${missing[@]}"; do
        if ! command -v "$dep" &>/dev/null; then
            error "安装失败：$dep"
            exit 1
        fi
    done
    success "所有依赖已成功安装！"
}

# 产品解析工具
parse_product_from_json() {
    local index="$1"
    local name=$(echo "$PRODUCTS" | jq -r ".[$index].name")
    local code=$(echo "$PRODUCTS" | jq -r ".[$index].productCode")
    echo "$name|$code"
}
# 环境变量清理函数
remove_env_other(){
    OS_NAME=$(uname -s)
    JB_PRODUCTS="idea clion phpstorm goland pycharm webstorm webide rider datagrip rubymine appcode dataspell gateway jetbrains_client jetbrainsclient"
    KDE_ENV_DIR="${USER_HOME}/.config/plasma-workspace/env"
    PROFILE_PATH="${USER_HOME}/.profile"
    ZSH_PROFILE_PATH="${USER_HOME}/.zshrc"
    PLIST_PATH="${USER_HOME}/Library/LaunchAgents/jetbrains.vmoptions.plist"

    if [ $OS_NAME = "Darwin" ]; then
        BASH_PROFILE_PATH="${USER_HOME}/.bash_profile"
    else
        BASH_PROFILE_PATH="${USER_HOME}/.bashrc"
    fi

    touch "${PROFILE_PATH}"
    touch "${BASH_PROFILE_PATH}"
    touch "${ZSH_PROFILE_PATH}"

    MY_VMOPTIONS_SHELL_NAME="jetbrains.vmoptions.sh"
    MY_VMOPTIONS_SHELL_FILE="${USER_HOME}/.${MY_VMOPTIONS_SHELL_NAME}"
    rm -rf "${MY_VMOPTIONS_SHELL_FILE}"

    if [ $OS_NAME = "Darwin" ]; then
        for PRD in $JB_PRODUCTS; do
            ENV_NAME=$(echo $PRD | tr '[a-z]' '[A-Z]')"_VM_OPTIONS"
            launchctl unsetenv "${ENV_NAME}"
        done
        rm -rf "${PLIST_PATH}"
        sed -i '' '/___MY_VMOPTIONS_SHELL_FILE="${HOME}\/\.jetbrains\.vmoptions\.sh"; if /d' "${PROFILE_PATH}" >/dev/null 2>&1
        sed -i '' '/___MY_VMOPTIONS_SHELL_FILE="${HOME}\/\.jetbrains\.vmoptions\.sh"; if /d' "${BASH_PROFILE_PATH}" >/dev/null 2>&1
        sed -i '' '/___MY_VMOPTIONS_SHELL_FILE="${HOME}\/\.jetbrains\.vmoptions\.sh"; if /d' "${ZSH_PROFILE_PATH}" >/dev/null 2>&1
    else
        sed -i '/___MY_VMOPTIONS_SHELL_FILE="${HOME}\/\.jetbrains\.vmoptions\.sh"; if /d' "${PROFILE_PATH}" >/dev/null 2>&1
        sed -i '/___MY_VMOPTIONS_SHELL_FILE="${HOME}\/\.jetbrains\.vmoptions\.sh"; if /d' "${BASH_PROFILE_PATH}" >/dev/null 2>&1
        sed -i '/___MY_VMOPTIONS_SHELL_FILE="${HOME}\/\.jetbrains\.vmoptions\.sh"; if /d' "${ZSH_PROFILE_PATH}" >/dev/null 2>&1
        rm -rf "${KDE_ENV_DIR}/${MY_VMOPTIONS_SHELL_NAME}"
    fi
    debug "清理三方工具环境变量完成"
}

remove_env_item_vars() {
    local env_key="$1"
    local shell_files=("${USER_HOME}/.bash_profile" "${USER_HOME}/.bashrc" "${USER_HOME}/.zshrc" "${USER_HOME}/.profile")
    local existing_files=()
    for file in "${shell_files[@]}"; do [ -f "$file" ] && existing_files+=("$file"); done
    [ ${#existing_files[@]} -eq 0 ] && { debug "未找到任何环境变量文件,跳过"; return; }

    for file in "${existing_files[@]}"; do
        if [ ! -w "$file" ]; then warning "文件 $file 不可写，跳过修改"; continue; fi
        debug "正在处理文件: $file,$env_key"
        local temp_file=$(mktemp "${file}.XXXXXX")
        grep -v -E "^(export[[:space:]]+)?${env_key}=" "$file" > "$temp_file"
        if ! cmp --silent "$file" "$temp_file"; then
            mv "$temp_file" "$file" && { info "已从 $file 中删除环境变量 [$env_key]"; }
        else
            rm -f "$temp_file"
        fi
        # source "$file"
    done
}
# 清理环境变量
remove_env_vars() {
    local index=0
    local product_count=$(echo "$PRODUCTS" | jq length)
    info "开始清理 JetBrains 相关环境变量"
    while [ $index -lt $product_count ]; do
        IFS='|' read -r name code <<< "$(parse_product_from_json "$index")"
        [ -z "$name" ] && break
        local upper_key="$(echo "${name}" | tr '[:lower:]' '[:upper:]').VMOPTIONS"
        local lower_key="$(echo "${name}" | tr '[:upper:]' '[:lower:]').vmoptions"
        local upper_key2="$(echo "${name}" | tr '[:lower:]' '[:upper:]')_VM_OPTIONS"
        remove_env_item_vars $upper_key
        remove_env_item_vars $lower_key
        remove_env_item_vars $upper_key2
        ((index++))
    done
    remove_env_other
}

# 获取配置信息
getConfig(){
    local key="$1"
    if [[ -z "$key" ]]; then
        error "缺少密钥参数"
        return 1
    fi
    
    local response=$(curl --silent --location --request GET "${BASE_URL}/shell/config.json" \
        --header 'Content-Type: application/json' \
        --header 'Accept: */*' \
        --header 'Connection: keep-alive')
    
    if [[ $? -ne 0 ]]; then
        error "请求失败"
        return 1
    fi
    
    password=$(echo "$response" | jq -r '.key // empty')
    license=$(echo "$response" | jq -r '.license // empty')
    jetjra=$(echo "$response" | jq -r '.zip // empty')

    # 验证密码
    if [ "$key" = "$password" ]; then
      echo "秘钥验证成功！"
      return 0
    else
      error "秘钥验证失败！"
      return 1
    fi
}

# 下载并处理文件函数
download_and_process(){
    local download_url="$1"

    info "下载链接参数======$download_url"

    if [[ -z "$download_url" ]]; then
        error "缺少下载链接参数"
        return 1
    fi


    # 从URL中提取文件名
    local filename=$(basename "$download_url" | cut -d'?' -f1)
    if [[ -z "$filename" ]] || [[ "$filename" == "/" ]]; then
        filename="jetbra.zip"
    fi
    
    local download_path="${dir_work}/${filename}"
    
    info "开始下载文件: $filename"
    info "下载路径: $download_path"
    
    # 使用curl下载文件，显示进度条
    if curl --location --progress-bar --output "$download_path" "$download_url"; then
        success "文件下载完成"
    else
        error "文件下载失败"
        return 1
    fi
    
    # 验证文件是否存在且不为空
    if [[ ! -f "$download_path" ]] || [[ ! -s "$download_path" ]]; then
        error "下载的文件不存在或为空"
        return 1
    fi
    
    info "文件大小: $(du -h "$download_path" | cut -f1)"
    
    # 如果是zip文件，解压处理
    if [[ "$filename" == *.zip ]]; then
        info "检测到ZIP文件，开始解压..."
        
        # 检查是否安装了unzip
        if ! command -v unzip &>/dev/null; then
            error "未找到unzip命令，请先安装unzip"
            return 1
        fi
        
        # 解压到工作目录
        if unzip -q "$download_path" -d "$dir_work"; then
            success "文件解压完成"
            
            # 删除zip文件
            rm -f "$download_path"
            info "已删除原始压缩文件"
            
            # 删除 __MACOSX 目录
            if [ -d "${dir_work}/__MACOSX" ]; then
                rm -rf "${dir_work}/__MACOSX"
                info "已删除 __MACOSX 目录"
            fi
            
            # 检查是否存在 jetbra 目录并移动其内容
            if [ -d "${dir_work}/jetbra" ]; then
                info "发现 jetbra 目录，正在移动内容到工作目录..."
                # 移动 jetbra 目录中的所有内容到工作目录
                mv "${dir_work}/jetbra/"* "${dir_work}/" 2>/dev/null || true
                # 移动隐藏文件
                mv "${dir_work}/jetbra/."* "${dir_work}/" 2>/dev/null || true
                # 删除空的 jetbra 目录
                rmdir "${dir_work}/jetbra" 2>/dev/null || true
                success "jetbra 目录内容已移动到工作目录"
            fi
            
            # 列出处理后的文件
            info "处理后的文件列表:"
            ls -la "$dir_work"
            
        else
            error "文件解压失败"
            return 1
        fi
    else
        info "文件下载完成，无需解压"
    fi
    
    return 0
}

# ============ 生成激活码 - 从服务器下载预生成的.key文件 =============
generate_license() {
    local obj_product_name="$1"
    local dir_product_name="$2"
    local file_license="${dir_config_jb}/${dir_product_name}/${obj_product_name}.key"

    [ -f "$file_license" ] && rm -f "$file_license"

    debug "从服务器下载授权文件"
    debug "保存路径: $file_license"

    # 从服务器下载预生成的授权文件
    response_code=$(curl -s -w "%{http_code}" -o "$file_license" "${LICENSE_URL}")

    if [ "$response_code" -eq 200 ] && [ -s "$file_license" ]; then
        success "${dir_product_name} 步骤完成"
    else
        rm -f "$file_license"  # 清理可能的错误文件
        error "${dir_product_name} 授权码无效或下载失败！"
    fi
}

# ============ 处理单个 Jetbrains 产品 =============
handle_jetbrains_dir() {
    local dir="$1"
    local dir_product_name=$(basename "$dir")
    local obj_product_name=""
    local obj_product_code=""

    for ((i = 0; i < $(echo "$PRODUCTS" | jq length); i++)); do
        IFS='|' read -r name code <<< "$(parse_product_from_json "$i")"
        local lowercase_dir=$(echo "${dir_product_name}" | tr '[:upper:]' '[:lower:]')
        if [[ "$lowercase_dir" == *"$name"* ]]; then
            obj_product_name="$name"
            obj_product_code="$code"
            break
        fi
    done

    [ -z "$obj_product_name" ] && return

    info "处理: ${dir_product_name}"

    local file_home="${dir}/.home"
    [ -f "$file_home" ] || {
        warning "未找到 ${dir_product_name} 的 .home 文件"
        return
    }

    debug ".home路径: $file_home"

    local install_path=$(cat "$file_home")
    [ -d "$install_path" ] || {
        warning "未找到 ${dir_product_name} 的安装路径！"
        return
    }

    debug ".home内容: $install_path"

    local dir_bin="${install_path}/bin"
    [ -d "$dir_bin" ] || {
        warning "${dir_product_name} 的 bin 目录不存在，请确认是否正确安装！"
        return
    }

    local dir_config_product="${dir_config_jb}/${dir_product_name}"

    # 先查找所有 .vmoptions 文件
    files=("${dir_config_product}"/*${FILE_VMOPTIONS})

    # 判断是否真的找到了文件
    if [[ -f "${files[0]}" ]]; then
      for file_vmoption in "${files[@]}"; do
        clean_vmoptions "$file_vmoption"
        clean_vmoptions "$file_vmoption"
      done
    else
      debug "未找到${dir_product_name} 的.vmoptions文件，将创建一个默认的"
      clean_vmoptions "${dir_config_product}/${obj_product_name}${FILE_VMOPTIONS}"
    fi

    # 判断${dir_config_product}/jetbrains_client.vmoptions是否存在，如果不存在则创建一个默认的
   local file_jetbrains_client="${dir_config_product}/jetbrains_client.vmoptions"
    if [ ! -f "${file_jetbrains_client}" ]; then
        append_vmoptions "${file_jetbrains_client}"
        else
        clean_vmoptions "${file_jetbrains_client}"
        append_vmoptions "${file_jetbrains_client}"
    fi

    # 调用修改后的授权生成函数
    generate_license "$obj_product_name" "$dir_product_name"
}

# ============ 主函数 =============
main(){
    clear
    show_ascii_weclome
    info "\r欢迎使用 JetBrains 脚本工具"
    warning "请确保你需要激活的软件已经启动过一次，如果不确定，请关闭脚本，将所有需要激活的软件启动后关闭在运行本脚本，否则检测不到软件目录"
    warning "请确保所有JB的开发工具 已经关闭掉了！！关闭掉后请按回车继续..."
    read -r
    info "处理中，请耐心等待..."

    check_and_install_deps

    if [ ! -d "${dir_config_jb}" ]; then
    error "未找到${dir_config_jb}目录"
    exit 1
    fi

    debug "config目录：${dir_config_jb}"
    remove_env_vars
    do_create_work_dir

        # 密码输入循环
    while true; do
        echo -e "\n${YELLOW}请输入密码 (按ESC退出):${NC}"
        read -r password
        
        # 检查是否按了ESC (在某些终端中ESC会显示为特殊字符)
        if [[ "$password" == $'\e' ]] || [[ "$password" == "exit" ]] || [[ "$password" == "quit" ]]; then
            warning "用户取消操作"
            exit 0
        fi
        
        if [[ -z "$password" ]]; then
            warning "密码不能为空，请重新输入"
            continue
        fi
        
        info "正在验证密码..."
        download_url=$(getConfig "$password")

        if [[ $? -eq 0 ]] ; then
            success "密码验证成功！"
            break
        else
            warning "密码验证失败，请重新输入 (输入 'exit' 退出)"
        fi
    done

    # 开始下载和处理文件
    info "LICENSE_URL ===== $LICENSE_URL"
    info "JETBRA_URL ===== $JETBRA_URL"
    if download_and_process "${JETBRA_URL}"; then
        success "文件下载和处理完成！"
    else
        error "文件下载或处理失败"
        exit 1
    fi
    for dir in "${dir_cache_jb}"/*; do
        [ -d "$dir" ] && handle_jetbrains_dir "$dir"
    done

    info "所有项处理完成，如果激活失败，请返回检查，使用手动方法去激活"
    info "如果打开软件后需要激活或者是试用期，请打开以下目录，里面有一个激活码文件，请勿动目录里的任何东西"
    info "目录：${dir_work}"
    info "如果输入激活码提示激活码不对，请使用卸载脚本，然后去使用手动版，手动版百分百激活"
    info "按回车退出脚本"
    sleep 1

}

main "$@"
